#include "comm_key.h"
#include <stdint.h>
#include <stddef.h>
#include "mlog.h"

#define MAX_KEY_NUM 3

keyInfo KeyArray[MAX_KEY_NUM];

enum {
    COMM_KEY_UNUSING = 0,
    COMM_KEY_INUSING = 1,
};

typedef enum {
    COMM_KEY_OK = 0,
    COMM_KEY_NO_THIS = 1,
    COMM_KEY_PRAR_ERR = 2

} func_return;

void key_InfoInit(void)
{
    uint8_t i = 0;
    for (i = 0; i < MAX_KEY_NUM; i++) {
        KeyArray[i].key_long_press_func = NULL;
        KeyArray[i].key_short_press_func = NULL;
        KeyArray[i].key_status = COMM_KEY_IDLE_STATUS;
        KeyArray[i].key_status_get_func = NULL;
        KeyArray[i].long_press_time = 0;
        KeyArray[i].shake_time = 0;
        KeyArray[i].short_press_time = 0;
        KeyArray[i].key_using_flag = COMM_KEY_UNUSING;
    }
}
keyInfo* key_Create(key_callback_func keystatus, key_callback_func shortfunc,
                    key_callback_func longfunc, uint32_t shorttime,
                    uint32_t longtime,
                    uint32_t shaketime)  //消抖时间，一般为15ms
{
    uint8_t i = 0;
    /*获取按键状态的函数一定不能为空*/
    if (keystatus == NULL) return NULL;
    for (i = 0; i < MAX_KEY_NUM; i++) {
        if (KeyArray[i].key_using_flag == COMM_KEY_UNUSING) {
            KeyArray[i].key_using_flag = COMM_KEY_INUSING;
            KeyArray[i].key_long_press_func = longfunc;
            KeyArray[i].key_short_press_func = shortfunc;
            KeyArray[i].key_status_get_func = keystatus;
            KeyArray[i].short_press_time = shorttime;
            KeyArray[i].long_press_time = longtime;
            KeyArray[i].shake_time = shaketime;
            return &KeyArray[i];
        }
    }
    return NULL;
}
uint8_t key_Delete(keyInfo* key)
{
    uint8_t i = 0;
    /*指针不能为空*/
    if (key == NULL) {
        mprintf(LOG_ERROR, "key para null!!!\r\n");
        return COMM_KEY_PRAR_ERR;
    }
    for (i = 0; i < MAX_KEY_NUM; i++) {
        if (&KeyArray[i] == key) {
            KeyArray[i].key_using_flag = COMM_KEY_UNUSING;
            KeyArray[i].key_long_press_func = NULL;
            KeyArray[i].key_short_press_func = NULL;
            KeyArray[i].key_status_get_func = NULL;
            return COMM_KEY_OK;
        }
    }
    mprintf(LOG_ERROR, "no this key!!!\r\n");
    /*无此按键*/
    return COMM_KEY_NO_THIS;
}

void key_HandleTask(void)
{
    uint8_t i = 0;

    for (i = 0; i < MAX_KEY_NUM; i++) {
        if (KeyArray[i].key_using_flag == COMM_KEY_INUSING) {
            GET_TICK(KeyArray[i].shake_timer.tick_temp);
            if ((KeyArray[i].shake_timer.tick_temp -
                 KeyArray[i].shake_timer.tick_begin) > KeyArray[i].shake_time) {
                switch (KeyArray[i].key_status) {
                    case COMM_KEY_IDLE_STATUS:
                        if (COMM_KEY_DOWN ==
                            KeyArray[i].key_status_get_func(NULL)) {
                            KeyArray[i].key_status = COMM_KEY_DOWN_SURE_STATUS;
                            /*开始去抖动*/
                            GET_TICK(KeyArray[i].shake_timer.tick_begin);
                        }
                        break;
                    case COMM_KEY_DOWN_SURE_STATUS:
                        if (COMM_KEY_DOWN ==
                            KeyArray[i].key_status_get_func(NULL)) {
                            KeyArray[i].key_status = COMM_KEY_UP_STATUS;
                            /*开始计时按下时间*/
                            GET_TICK(KeyArray[i].key_timer.tick_begin);
                        } else {
                            KeyArray[i].key_status = COMM_KEY_IDLE_STATUS;
                        }
                        break;
                    case COMM_KEY_UP_STATUS:
                        if (COMM_KEY_UP ==
                            KeyArray[i].key_status_get_func(NULL)) {
                            KeyArray[i].key_status = COMM_KEY_UP_STATUS;
                            GET_TICK(KeyArray[i].key_timer.tick_temp);

                            if ((KeyArray[i].key_timer.tick_temp -
                                 KeyArray[i].key_timer.tick_begin) >
                                KeyArray[i].long_press_time) {
                                if (KeyArray[i].key_long_press_func != NULL) {
                                    KeyArray[i].key_long_press_func(NULL);
                                } else {
                                    mprintf(LOG_INFO,
                                            "no long key press callback func, "
                                            "key index：%d。\r\n",
                                            i);
                                }
                            } else {
                                if (KeyArray[i].key_short_press_func != NULL) {
                                    KeyArray[i].key_short_press_func(NULL);
                                } else {
                                    mprintf(LOG_INFO,
                                            "no short key press callback func, "
                                            "key index：%d。\r\n",
                                            i);
                                }
                            }
                            KeyArray[i].key_status = COMM_KEY_IDLE_STATUS;
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }
}
